using System;
using System.Collections.Generic;
using System.Threading;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
using Navigant.Infrastructure;
using Navigant.Infrastructure.Cases;
using Navigant.Infrastructure.ClientPortals;
using Navigant.Infrastructure.Helpers;
using Navigant.Model.Cases;
using Navigant.Model.ClientPortals;
using Navigant.Model.Custodians;
using Navigant.Model.PreservationNotices;

namespace Navigant.Web
{
    public class AcknowledgeWithCode : Page
    {
        private ICase caseSite;
        private IClientPortal portal;
        private IUnitOfWork unitOfWork;
        private string itemGuidString;
        private PreservationNoticeService service;
        private IList<PreservationNotice> historyList;
        private PreservationNotice lastEvent;
        private bool authenticationNotRequired;
        private bool acknowledgementsShutdown;
        protected Panel acknowledgePanel;
        protected TextBox confirmationCodeTextBox;
        protected Button acknowledgeButton;
        protected Panel successPanel;
        protected Panel reattemptPanel;
        protected TextBox reattemptConfirmationCodeTextBox;
        protected Button reattemptButton;
        protected Panel existingPanel;
        protected Label dateLabel;
        protected Label acknowledgeLabel;
        protected Label successLabel;
        protected Label reattemptLabel;
        protected Label existingLabel;

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            try
            {
                if (this.Request["siteCollection"] != null)
                {
                    try
                    {
                        Guid siteGuid = new Guid(this.Request["siteCollection"]);
                        Guid webGuid = new Guid(this.Request["case"]);
                        SPSecurity.RunWithElevatedPrivileges(delegate()
                        {
                            this.portal = ClientPortalService.GetClientPortalBy(siteGuid);
                            this.authenticationNotRequired = this.portal.EmailAuthenticationNotRequired;
                            this.acknowledgementsShutdown = this.portal.AcknowledgementsShutdown;
                            this.caseSite = CaseService.GetCaseBy(siteGuid, webGuid);
                        });
                        this.unitOfWork = new UnitOfWork();
                    }
                    catch (Exception ex)
                    {
                        Logger.LogError(ex, this.caseSite);
                        Response.Write(Constants.DefaultErrorMessage);
                        this.EndResponse();
                    }

                    // Check to see if the case site or the portal has customized the text for the panels,
                    // if they have then use their text instead of the default in the page
                    string acknowledgeText = ConfigurationSettingsHelper.GetString(this.caseSite,
                        Constants.AcknowledgeTextSettingName);
                    if (!string.IsNullOrEmpty(acknowledgeText))
                    {
                        this.acknowledgeLabel.Text = acknowledgeText;
                    }

                    string successText = ConfigurationSettingsHelper.GetString(this.caseSite,
                        Constants.SuccessTextSettingName);
                    if (!string.IsNullOrEmpty(successText))
                    {
                        this.successLabel.Text = successText;
                    }

                    string reattemptText = ConfigurationSettingsHelper.GetString(this.caseSite,
                        Constants.ReattemptTextSettingName);
                    if (!string.IsNullOrEmpty(reattemptText))
                    {
                        this.reattemptLabel.Text = reattemptText;
                    }

                    string existingText = ConfigurationSettingsHelper.GetString(this.caseSite,
                        Constants.ExistingTextSettingName);
                    if (!string.IsNullOrEmpty(existingText))
                    {
                        this.existingLabel.Text = existingText;
                    }

                    // Display a message if acknowledgements are shut down
                    if (this.acknowledgementsShutdown)
                    {
                        string message = Constants.DefaultShutdownMessage;
                        if (!string.IsNullOrEmpty(this.portal.AcknowledgementsShutdownMessage))
                        {
                            message = this.portal.AcknowledgementsShutdownMessage;
                        }
                        this.Response.Write(message);
                        this.EndResponse();
                    }

                    if (this.Request["item"] != null)
                    {
                        this.itemGuidString = this.Request["item"];
                        this.service = new PreservationNoticeService(this.caseSite, this.unitOfWork, true);

                        SPSecurity.RunWithElevatedPrivileges(delegate()
                        {
                            // This list is already in descending order from the stored procedure
                            this.historyList = this.service.FindBySiteAnd(itemGuidString);
                        });

                        // Get the first item in the list (which is the last chronological event)
                        if (this.historyList != null && this.historyList.Count > 0)
                        {
                            this.lastEvent = this.historyList[0];
                        }
                    }
                }
            }
            catch (ThreadAbortException) { }
            catch (Exception ex)
            {
                Logger.LogError(ex, this.caseSite);
                Response.Write(Constants.DefaultErrorMessage);
                this.EndResponse();
            }
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            if (!this.IsPostBack && this.lastEvent != null)
            {                
                if (this.authenticationNotRequired)
                {
                    try
                    {
                        this.SaveAcknowledgement();
                        this.acknowledgePanel.Visible = false;
                        this.reattemptPanel.Visible = false;
                        this.successPanel.Visible = true;
                    }
                    catch (Exception ex)
                    {
                        Response.Write(ex.ToString());
                    }
                }
                else
                {
                    this.acknowledgePanel.Visible = true;
                    this.reattemptPanel.Visible = false;
                    this.successPanel.Visible = false;
                    this.confirmationCodeTextBox.Focus();
                }                
            }
        }

        protected void AcknowledgeButtonClick(object sender, EventArgs e)
        {
            this.AttemptAcknowledge(this.confirmationCodeTextBox.Text);
        }

        protected void ReattemptButtonClick(object sender, EventArgs e)
        {
            this.AttemptAcknowledge(this.reattemptConfirmationCodeTextBox.Text);
        }

        private void AttemptAcknowledge(string confirmationCode)
        {
            try
            {
                if ((this.lastEvent.MessageIdentifier.ToLower().Trim().Substring(0, 
                    Navigant.Common.Constants.ConfirmationCodeLength) == confirmationCode.ToLower().Trim()))
                {
                    this.SaveAcknowledgement();
                    this.acknowledgePanel.Visible = false;
                    this.reattemptPanel.Visible = false;
                    this.successPanel.Visible = true;
                }
                else
                {
                    this.acknowledgePanel.Visible = false;
                    this.reattemptPanel.Visible = true;
                    this.reattemptConfirmationCodeTextBox.Focus();
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, this.caseSite);
                Response.Write(Constants.DefaultErrorMessage);
                this.EndResponse();
            }
        }

        private void EndResponse()
        {
            try
            {
                HttpContext.Current.ApplicationInstance.CompleteRequest(); 
            }
            catch { }
        }

        private void SaveAcknowledgement()
        {
            this.lastEvent.Acknowledge();
            this.service.AddPreservationNotice(this.lastEvent);
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                this.unitOfWork.Commit();
            });
            CustodianService service = new CustodianService(this.caseSite, this.unitOfWork, true);
            service.SaveCustodian(this.lastEvent.To);
            this.unitOfWork.Commit();
        }        
    }
}
